<template>
    <a-upload
        v-bind="$attrs"
        :accept="accept.join()"
        :list-type="listType"
        :headers="{
            'Content-Disposition': 'form-data_cors;name=file',
        }"
        :file-list="fileList"
        :data="data"
        :name="name"
        :showUploadList="showUploadList"
        :before-upload="beforeUpload"
        :customRequest="customRequest"
        :remove="remove"
        @change="handleChange"
        @preview="preview"
    >
        <a-button v-if="listType === 'text'">
            <a-icon type="upload" /> {{ uploadText }}
        </a-button>
        <div v-else>
            <a-icon :type="loading ? 'loading' : 'plus'" />
            <div class="ant-upload-text">{{ uploadText }}</div>
        </div>
    </a-upload>
</template>
<script>
import { uploadApi } from "@/api/common";
import { appConfig } from "@/config";
export default {
    model: {
        prop: "value",
        event: "change",
    },
    props: {
        value: [String, Array, Object],
        http: {
            type: Function,
            default: uploadApi,
        },
        // 接收类型
        accept: {
            type: Array,
            default: () => [""],
        },
        name: {
            type: String,
            default: "file",
        },
        multiple: {
            type: Boolean,
            default: false,
        },
        data: {
            type: Object,
            default: () => {},
        },
        // 文件大小上限
        maxSize: {
            type: Number,
            default: Infinity,
        },
        listType: {
            type: String,
            default: "text",
        },
        max: {
            type: Number,
            default: 15,
        },
        rules: {
            type: Array,
            validator: (rules) =>
                rules.every((rule) => typeof rule.validator === "function"),
        },
        showUploadList: {
            type: Boolean,
            default: true,
        },
        uploadText: {
            type: String,
            default: "附件上传",
        },
        isPrview: {
            type: Boolean,
            default: true,
        },
    },
    data() {
        return {
            loading: false,
            fileList: [],
            images: [],
        };
    },
    computed: {
        ownFileUrl() {
            return appConfig.baseUrl.files;
        },
    },
    watch: {
        value: {
            handler(value) {
                console.log(value, "val");
                if (!value) return (this.fileList = []);
                const type = Object.prototype.toString.call(value);
                if (type === "[object String]") value = [{ url: value }];
                if (type === "[object Object]") value = [value];
                this.fileList = value.map((item) => ({
                    status: item.status || "done",
                    name:
                        item.name ||
                        item.original_name ||
                        item.url?.substring(0, 20) + "..." ||
                        item.url,
                    uid: item.id || item.url,
                    thumbUrl: this.ownFileUrl + (item.url || item.path || item),
                    response: { ...item },
                }));
            },
            immediate: true,
        },
    },
    methods: {
        handleChange({ file, fileList = [] }) {},
        emitChange() {
            let data =
                this.fileList
                    .filter((item) => item.status === "done")
                    .map((item) => ({
                        ...item,
                        ...(item.response || {}),
                    })) || [];
            data = this.max > 1 ? data : data && data[0];
            this.$emit("change", data);
        },
        beforeUpload(file) {
            const rules = [
                {
                    validator: (data) =>
                        this.accept.some((type) => {
                            let isAccord =
                                data.name.toLowerCase().search(type) !== -1;
                            if (!isAccord) {
                                isAccord =
                                    data.type.toLowerCase().search(type) !== -1;
                            }
                            return isAccord;
                        }),
                    message: "文件格式不符合要求",
                },
                {
                    validator: (data) => data.size <= this.maxSize,
                    message: `文件不能超过 ${Math.floor(
                        this.maxSize / 1024 / 1024
                    )} M`,
                },
            ];
            // 附加自定义验证规则
            rules.push(...(this.rules || []));
            const result = rules.find((rule) => !rule.validator(file));
            if (result) {
                if (this.$parent.error) {
                    this.$emit("error", result.message);
                } else {
                    this.$message.error(result.message);
                }
                return Promise.reject();
            }
            return Promise.resolve();
        },
        customRequest({ file }) {
            this.loading = true;
            const formData = new FormData();
            formData.append(this.name, file);
            this.http(formData).then((res) => {
                this.fileList.push({
                    status: res.status || "done",
                    name: res.original_name || res.url,
                    uid: res.id || res.url,
                    thumbUrl: this.ownFileUrl + (res.url || res.path),
                    response: { ...res },
                });
                this.emitChange();
                this.images = this.fileList.map((item) => item.thumbUrl);
                this.loading = false;
            });
        },
        preview(file) {
            if (this.isPrview) {
                this.$viewerApi({
                    images: this.images,
                });
            } else {
                this.downloadFile(file.name, file.thumbUrl);
            }
        },
        remove(file) {
            this.fileList = this.fileList.filter((x) => x.uid !== file.uid);
        },
        downloadFile(name, url) {
            const a = document.createElement("a");

            const rootDocument = window.document;

            // void 0 相当于 undefined
            if (a.download !== void 0) {
                // 在新窗口打开
                a.target = "_blank";
                a.style.display = "none";
                // 为 a 设置属性 href
                a.setAttribute("href", url);
                // 为 a 设置 download 属性
                a.setAttribute("download", name);
                rootDocument.body.appendChild(a);
                a.dispatchEvent(new MouseEvent("click"));
                rootDocument.body.removeChild(a);

                // setTimeout(() => {
                //   URL.revokeObjectURL(url);
                // }, 100);
            } else if (navigator.msSaveOrOpenBlob) {
                // IE10+
                // navigator.msSaveOrOpenBlob(blob, name);
            }
        },
    },
};
</script>
<style scoped lang="less">
.ant-upload-text {
    padding-top: 10px;
}
</style>
